package com.nbx.library.glutes;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import javax.microedition.khronos.opengles.GL10;


public class shape{
	
	/******************************************************************
	 *                     SolidBox                                   *
	 ******************************************************************/
	private static class Box {
		private static Box mBox = null;
		
		private static final int STATE_INIT = 0;
		private static final int STATE_CUBE_SOLID = 1;
		private static final int STATE_CUBE_WIRE = 2;
		private static final int STATE_BOX_SOLID = 3;
		private static final int STATE_BOX_WIRE = 4;
		
		private static int mState = STATE_INIT;
        private static float vertices[] = {
                -1.0f, -1.0f, -1.0f,
                 1.0f, -1.0f, -1.0f,
                 1.0f,  1.0f, -1.0f,
                -1.0f,  1.0f, -1.0f,
                
                -1.0f, -1.0f,  1.0f,
                 1.0f, -1.0f,  1.0f,
                 1.0f,  1.0f,  1.0f,
                -1.0f,  1.0f,  1.0f,
        };

        private static float colors[] = {
                0.0f,  0.0f,  0.0f,  1.0f,
                1.0f,  0.0f,  0.0f,  1.0f,
                1.0f,  1.0f,  0.0f,  1.0f,
                0.0f,  1.0f,  0.0f,  1.0f,
                0.0f,  0.0f,  1.0f,  1.0f,
                1.0f,  0.0f,  1.0f,  1.0f,
                1.0f,  1.0f,  1.0f,  1.0f,
                0.0f,  1.0f,  1.0f,  1.0f,
        };
        
        private static byte indicew[] = {
                3, 2, 1, 0,
                4, 5, 6, 7,
                5, 1, 2, 6,
                7, 3, 0, 4
        };

        private static byte indices[] = {
            0, 4, 5,    0, 5, 1,
            1, 5, 6,    1, 6, 2,
            2, 6, 7,    2, 7, 3,
            3, 7, 4,    3, 4, 0,
            4, 7, 6,    4, 6, 5,
            3, 0, 1,    3, 1, 2  };

		public static void drawSolidBox(GL10 gl, float Width, float Depth,
				float Height) {
			if (mBox == null) {
				mBox = new Box();
			}

			if (mSizex != Width || mSizey != Height || mSizez != Depth) {
				mSizex = Width;
				mSizey = Height;
				mSizez = Depth;
				mSize = 0.0f;// reset

				float w = (float) (Width / 2.0);
				float h = (float) (Height / 2.0);
				float d = (float) (Depth / 2.0);

				float v[] = new float[24];
				for (int i = 0; i < 24; i += 3) {
					v[i] = vertices[i] * w;
					v[i + 1] = vertices[i + 1] * h;
					v[i + 2] = vertices[i + 2] * d;
				}
				mVertexBuffer = util.createFloatBuffer(v);
			}

			if(mState == STATE_CUBE_SOLID || mState == STATE_CUBE_WIRE || mState == STATE_INIT){
				mIndexBuffer = util.createByteBuffer(indices);
				mState = STATE_BOX_SOLID;
			}
			
			if(mIndexBuffer == null){
				mColorBuffer = util.createFloatBuffer(colors);
			}

			gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
			gl.glEnableClientState(GL10.GL_COLOR_ARRAY);

			gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
			gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
			gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE,
					mIndexBuffer);

			gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
			gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		}
	    
	    public static void drawSolidCube(GL10 gl, float size){
	    	if(mBox == null){
	    		mBox = new Box();
	    	}
	    	
	    	if(mSize != size){
	    		mSize = size;
	    		mSizex = 0.0f; //reset
	    		float s = (float)(size / 2.0);
	    		float v[] = new float[24];
	    		for(int i=0; i<24; i++){
	    			v[i] = vertices[i] * s;
	    		}
	    		mVertexBuffer = util.createFloatBuffer(v);
	    	}
	    	
	    	if(mState == STATE_BOX_SOLID || mState == STATE_BOX_WIRE|| mState == STATE_INIT){
				mIndexBuffer = util.createByteBuffer(indices);
				mState = STATE_CUBE_SOLID;
			}	
	    	
			if(mColorBuffer == null){
				mColorBuffer = util.createFloatBuffer(colors);
			}	    	
	    	
	    	gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
	    	gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	    	
	    	gl.glColorPointer(4, GL10.GL_FLOAT, 0, mColorBuffer);
	        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
	        gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
	        
	        gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
	        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
	    }
	    
	    public static void drawWireCube(GL10 gl, float size){
	    	if(mBox == null){
	    		mBox = new Box();
	    	}
	    	
	    	if(mSize != size){
	    		mSize = size;
	    		mSizex = 0.0f; //reset
	    		float s = (float)(size / 2.0);
	    		float v[] = new float[24];
	    		for(int i=0; i<24; i++){
	    			v[i] = vertices[i] * s;
	    		}
	    		mVertexBuffer = util.createFloatBuffer(v);
	    	}
	    	
			if(mState == STATE_BOX_SOLID || mState == STATE_BOX_WIRE|| mState == STATE_INIT){
				mIndexBuffer = util.createByteBuffer(indicew);
				mState = STATE_CUBE_WIRE;
			}		    	
	    	
	    	gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	    	
	        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
	        
			for (int i = 0; i < 4; i++) {
				gl.glDrawElements(GL10.GL_LINE_LOOP, 4, GL10.GL_UNSIGNED_BYTE,
						mIndexBuffer.position(i*4));
			}
	        
	        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);	    	
	    }
	    
	    
	    public static void drawWireBox(GL10 gl, float Width, float Depth,
				float Height){
	    	if(mBox == null){
	    		mBox = new Box();
	    	}
	    	
			if (mSizex != Width || mSizey != Height || mSizez != Depth) {
				mSizex = Width;
				mSizey = Height;
				mSizez = Depth;
				mSize = 0.0f;// reset

				float w = (float) (Width / 2.0);
				float h = (float) (Height / 2.0);
				float d = (float) (Depth / 2.0);

				float v[] = new float[24];
				for (int i = 0; i < 24; i += 3) {
					v[i] = vertices[i] * w;
					v[i + 1] = vertices[i + 1] * h;
					v[i + 2] = vertices[i + 2] * d;
				}
				mVertexBuffer = util.createFloatBuffer(v);
			}
	    	
			if(mState == STATE_BOX_SOLID || mState == STATE_BOX_WIRE|| mState == STATE_INIT){
				mIndexBuffer = util.createByteBuffer(indicew);
				mState = STATE_CUBE_WIRE;
			}		    	
	    	
	    	gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
	    	
	        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mVertexBuffer);
	        
			for (int i = 0; i < 4; i++) {
				gl.glDrawElements(GL10.GL_LINE_LOOP, 4, GL10.GL_UNSIGNED_BYTE,
						mIndexBuffer.position(i*4));
			}
	        
	        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);		    	
	    }

	    //Private member for Solid Box
	    private static FloatBuffer   mVertexBuffer = null;
	    private static ByteBuffer  mIndexBuffer = null;
	    private static FloatBuffer   mColorBuffer;

	    private static float mSize = 0.0f;
	    
	    private static float mSizex = 0.0f;
	    private static float mSizey = 0.0f;
	    private static float mSizez = 0.0f;
	}
	
	/**
	 * 
	 * @param gl
	 * @param size
	 */
	public static void glutSolidCube(GL10 gl, float size) {
		Box.drawSolidCube(gl, size);
	}
	
	/**
	 * 
	 * @param gl
	 * @param Width
	 * @param Depth
	 * @param Height
	 */
    public static void glutSolidBox(GL10 gl, float Width, float Depth, float Height){
    	Box.drawSolidBox(gl, Width, Depth, Height);
    }

    /**
     * 
     * @param gl
     * @param size
     */
    public static void glutWireCube(GL10 gl, float size){
    	Box.drawWireCube(gl, size);
    }
    
    /*
     * 
     */
    public static void glutWireBox(GL10 gl, float Width, float Depth, float Height){
    	Box.drawWireBox(gl, Width, Depth, Height);
    }
    
    ////////////////////////////////////////////////////////////////////////
    
    private static class Sphere {
    	private static Sphere mSphere = null;
    }
    public static void glutSolidSphere(GL10 gl, float radius, int slices, int stacks){
    	
    }
    
    
    public static void glutWireSphere(GL10 gl, float radius, int slices, int stacks){
    	
    }   
    
    public static void glutSolidTorus(GL10 gl, float ir, float or, int sides, int rings){
    	
    }
}